package com.asp.aspchain.mmwytransaction.service.impl;

import com.alibaba.fastjson.JSON;
import com.asp.aspchain.core.contract.ERC721Full_sol_ERC721Full;
import com.asp.aspchain.core.dao.*;
import com.asp.aspchain.core.ethereum.EthService;
import com.asp.aspchain.core.model.*;
import com.asp.aspchain.core.util.AjaxResult;
import com.asp.aspchain.core.util.ContractUtil;
import com.asp.aspchain.core.util.DateUtil;
import com.asp.aspchain.mmwytransaction.request.TransactionCommitReq;
import com.asp.aspchain.mmwytransaction.service.CoaCommitService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.ECKeyPair;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;

import java.io.IOException;
import java.math.BigInteger;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zhongzifeng
 */
@Service
public class CoaCommitServiceImpl implements CoaCommitService {
	private final static Logger logger = Logger.getLogger(CoaCommitServiceImpl.class);

	@Value("${mmwy.accountkey}")
	private String accountKey;

	@Value("${contract.cid}")
	private Integer cid;

    @Autowired
	private EthService ethService;

	@Autowired
	private MgrAccountMapper mgrAccountMapper;

	@Autowired
	private TocAccountMapper tocAccountMapper;

	@Autowired
	private AppBaseMapper appBaseMapper;

	@Autowired
    private TransactionMapper transactionMapper;

	@Autowired
	private AssetMapper assetMapper;

	@Autowired
	private SequenceMapper sequenceMapper;

	@Autowired
	private ContractUtil contractUtil;


	/**
	 * 账户充值
	 * @param json transaction commit param
	 * @return
	 */
	@Override
	public AjaxResult coaCommit(String json){
        AjaxResult result = new AjaxResult();
        try {
			// 转换参数至实体
			TransactionCommitReq req = JSON.parseObject(json, TransactionCommitReq.class);
			MgrAccountModel selectMgrAccount = new MgrAccountModel();
			// 校验充值账户是否属于指定appmark
			selectMgrAccount.setAccoutkey(accountKey);
			MgrAccountModel mgrAccountModel = mgrAccountMapper.selectOne(selectMgrAccount);
			String appmark = req.getAppmark();
			AppBaseModel selectAppBase = new AppBaseModel();
			selectAppBase.setAppmark(appmark);
			AppBaseModel appBaseModel = appBaseMapper.selectOne(selectAppBase);
			if(appBaseModel==null || "".equals(appBaseModel.getAppid())){
				logger.error("COA-MMWY-充值失败，无appmark相关配置");
				return new AjaxResult("1","充值失败，无appmark相关配置","");
			}
			String toAccount = req.getAccountid();
			TocAccountModel tocAccountModel = tocAccountMapper.selectById(toAccount);
			if(tocAccountModel==null ||
					!appBaseModel.getAppid().equals(tocAccountModel.getAppid())){
				logger.error("COA-MMWY-充值失败，非appid："+appmark+" 关联用户");
				return new AjaxResult("1","充值失败，非appid："+appmark+" 关联用户","");
			}
			// 校验orderid是否已经使用
			String orderId = req.getOrderid();
			Wrapper<TransactionModel> wrapper = new EntityWrapper<TransactionModel>();
			wrapper.eq("orderid",orderId);
			int orderIdCount = transactionMapper.selectCount(wrapper);
			if(orderIdCount>0){
				logger.error("COA-MMWY-充值失败，orderid："+orderId+" 已存在");
				return new AjaxResult("1","充值失败，orderid："+orderId+" 已存在","");
			}


            // 检查asset
			String asset = req.getAsset();
			if(asset==null){
				logger.error("COA-MMWY-充值失败，asset为空");
				return new AjaxResult("1","充值失败，asset为空","");
			}
			// 编码asset
			Base64.Encoder encoder = Base64.getEncoder();
			byte[] assetBytes = asset.getBytes();
			assetBytes = encoder.encode(assetBytes);
			// 生成assetid
			String assetid = sequenceMapper.getNextStringValue("assetid");
			AssetModel assetModel = new AssetModel();
			assetModel.setAssetid(assetid);
			assetModel.setCreatetime(new Date());
			assetModel.setAsset(new String(assetBytes));
			// 入库
			assetMapper.insert(assetModel);

//			// 获取keystore文件
//            Credentials credentials = contractUtil.getCredentialsByCid(cid);
//            if(credentials == null){
//				logger.error("COA-MMWY-充值失败，keystore获取失败");
//				return new AjaxResult("1","充值失败，keystore获取失败","");
//			}

            // 获取合约类
			ERC721Full_sol_ERC721Full contract = (ERC721Full_sol_ERC721Full) contractUtil.getContract(cid);
			if(contract == null){
				logger.error("COA-MMWY-充值失败，contract获取失败");
				return new AjaxResult("1","充值失败，contract获取失败","");
			}

//			BigInteger value = req.getTokenvalue();
//			String password = req.getPassword();
//			String from = mgrAccountModel.getAccountid();
//			//Transaction createEtherTransaction = new Transaction(from, null, null, null, toAccount, value,  null);
//			Transaction createEtherTransaction = null;

			TransactionReceipt send = contract.approve(req.getAccountid(),new BigInteger(assetid)).send();
			System.out.println(send.getTransactionHash());
			System.out.println(send.getBlockNumber());

//			String transactionHash = ethService.sendTransaction(createEtherTransaction,password);
//			logger.info("COA-MMWYAPP-区块链生成的交易号(transactionHash)："+transactionHash);
//			// 请求异常情况处理
//			if(StringUtils.isEmpty(transactionHash)){
//                logger.error("COA-MMWY-充值失败，TransactionHash 为空");
//                result.setStatus("1");
//                result.setMessage("充值失败，TransactionHash 为空");
//                return result;
//            }
//
//
//
//
//
            // 成功发起交易写入交易记录表
//            logger.info("COA-MMWY-写入交易记录");
//            TransactionModel transactionModel = new TransactionModel();
//            transactionModel.setTradeid("ZL" + System.currentTimeMillis());
//            transactionModel.setOrdertime(DateUtil.parseTime(req.getOrdertime()));
//            transactionModel.setOrderid(orderId);
//			transactionModel.setAppid(appBaseModel.getAppid()+"appid");
//			transactionModel.setTradetype("0001");
//			transactionModel.setCreatetime(new Date());
//			transactionModel.setUpdatetime(new Date());
//			transactionModel.setFromaaccountid(from);
//			transactionModel.setFromtype("00");
//			transactionModel.setToaaccountid(toAccount);
//			transactionModel.setTotype("00");
//			transactionModel.setTokentype("tst");
//			transactionModel.setTokenvalue(value);
//			transactionModel.setTransactionid(transactionHash);
//			transactionModel.setStatus("00");
//			transactionModel.setTranstime(new Date());
//            transactionMapper.insert(transactionModel);

            result.setStatus("0");
            result.setMessage("交易提交成功");
            Map<String,Object> context = new HashMap<String,Object>(3);
//            context.put("tradeid",transactionModel.getTradeid());
//            context.put("transactionid",transactionModel.getTransactionid());
//            context.put("status",transactionModel.getStatus());
            result.setContext(context);
		} catch (IOException e) {
			e.printStackTrace();
            logger.error("COA-MMWY-充值失败，连接以太坊失败");
            result.setStatus("1");
            result.setMessage("充值失败，连接以太坊失败");
            return result;
		} catch (Exception e) {
            e.printStackTrace();
        }
        return result;
	}



}
